<?php
class Usuario extends Doctrine_Record {
    public function setTableDefinition() {
        $this->setTableName('usuario');
        $this->hasColumn('nombre','string', 150);
        $this->hasColumn('apellido','string', 150);
        $this->hasColumn('genero','integer', 1); //1 - masculino / 2 - femenino
        $this->hasColumn('email','string', 150);
        $this->hasColumn('pass','string', 32);
        $this->hasColumn('twitter','string', 255);
        $this->hasColumn('facebook','string', 255);
        $this->hasColumn('idFacebook','string', 255);
        $this->hasColumn('imagesFacebook','integer', 1);
        $this->hasColumn('blog','string', 255);
        $this->hasColumn('web','string', 255);
        $this->hasColumn('fechaNacimiento','date');
        $this->hasColumn('ocupacion','string', 255);
        $this->hasColumn('id_estado','integer');
        $this->hasColumn('id_imagen','integer'); //Imagen: https://graph.facebook.com/'+user.id+'/picture
        $this->hasColumn('id_distrito','integer');
        $this->hasColumn('id_marker_favorito','integer'); //markers favoritos del usuario relacion n a n
        $this->hasColumn('id_cooperativa_favorito','integer'); //markers favoritos del usuario relacion n a n
        $this->hasColumn('id_publicacion_favorita','integer'); //publicaciones favoritas del usuario relacion n a n
        $this->hasColumn('id_usuario_favorito','integer'); //usuarios que sigue el usuario relacion n a n
        $this->hasColumn('id_seguidor','integer'); //llamada recursiva a si mismo porque un usuario puede tener usuarios (como favoritos)
        $this->hasColumn('codigo','string',32);
    }

    public function setUp(){
        $this->hasOne('Estado as estado',array(
            'local'=>'id_estado',
            'foreign'=>'id'
        ));
        $this->hasOne('Imagen as imagen',array(
            'local'=>'id_imagen',
            'foreign'=>'id'
        ));
        $this->hasOne('Distrito as distrito',array(
            'local'=>'id_distrito',
            'foreign'=>'id'
        ));
        $this->hasMany('Publicacion as publicaciones',array(
            'local'=>'id',
            'foreign'=>'id_owner'
        ));
        $this->hasMany('Comentario as comentarios',array(
            'local'=>'id',
            'foreign'=>'id_owner'
        ));
        $this->hasMany('Marker as markerCargados',array(
            'local'=>'id',
            'foreign'=>'id_cargador'
        ));
        $this->hasMany('Marker as markersFavoritos', array(
            'local' => 'id_marker_favorito',
            'foreign' => 'id_seguidor',
            'refClass' => 'FavoritoMarker'
        ));
        $this->hasMany('Cooperativa as cooperativasFavoritas', array(
            'local' => 'id_cooperativa_favorito',
            'foreign' => 'id_seguidor',
            'refClass' => 'FavoritoCooperativa'
        ));
        $this->hasMany('Usuario as usuariosFavoritos', array(
            'local' => 'id_usuario_favorito',
            'foreign' => 'id_seguidor',
            'refClass' => 'FavoritoUsuario'
        ));
        $this->hasMany('Publicacion as publicacionesFavoritas', array(
            'local' => 'id_publicacion_favorita',
            'foreign' => 'id_seguidor',
            'refClass' => 'FavoritoPublicacion'
        ));
    }

    //INCIO DE GETERS Y SETERS
    public function getNombre () {
        return utf8_decode($this->_get('nombre'));
    }
    public function setNombre ($nombre) {
        $this->_set('nombre', utf8_encode($nombre));
    }

    public function getApellido () {
        return utf8_decode($this->_get('apellido'));
    }
    public function setApellido ($apellido) {
        $this->_set('apellido', utf8_encode($apellido));
    }
    
    public function getImagen () {
        if (!$this->_get('id_imagen')) {
            $imagen = Doctrine::getTable('imagen')->find(3); //imagen por default
        } else {
            $imagen = Doctrine::getTable('imagen')->find($this->_get('id_imagen'));
        }
        return $imagen;
    }

    public function getOcupacion () {
        return utf8_decode($this->_get('ocupacion'));
    }
    public function setOcupacion ($ocupacion) {
        $this->_set('ocupacion', utf8_encode($ocupacion));
    }
    
    public function getFechaNacimiento () {
        if ($this->_get('fechaNacimiento')) {
            $fecha = explode('-', $this->_get('fechaNacimiento'));
            $fecha = $fecha[2].'-'.$fecha[1].'-'.$fecha[0];
        } else {
            $fecha = '';
        }
        return $fecha;
    }
    public function setFechaNacimiento ($fecha) {
        $fecha = explode('-', $fecha);
        $this->_set('fechaNacimiento', $fecha[2].'-'.$fecha[1].'-'.$fecha[0]);
    }

    public function setPass ($pass) {
        $this->_set('pass', md5($pass));
    }
    //FIN SETERS Y GETERS

    public static function syst () {
        return Doctrine::getTable('usuario')->find(1);
    }

    public static function admin () {
        return Doctrine::getTable('usuario')->find(2);
    }

    public function toString () {
        return $this->nombre.' '.$this->apellido;
    }

    //FUNCIONES DE SEGURIDAD
    public function asignarCodigo () {
        $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890';
        $myCodigo = '';
        do {
            for($i=0;$i<32;$i++){
                $myCodigo .= substr($string,rand(0,62),1);
            }
            $codigo = Doctrine::getTable('codigo')->findOneByContenido($myCodigo);
        } while ($codigo);
        $objetoCodigo = new Codigo ();
        $objetoCodigo->contenido = $myCodigo;
        $objetoCodigo->save();
        $this->codigo = $myCodigo;
        $this->_set('codigo',$myCodigo);
    }

    static public function isValido ($email, $pass) {
        $q = Doctrine_Query::create()
            ->select('u.*')
            ->from('Usuario u')
            ->where('u.email = ?', utf8_encode($email));
        $usuario = $q->execute();
        return ($usuario[0]->pass == md5($pass))?$usuario[0]:false;
    }
    
    public function cambiarPass ($passActual, $passNueva) {
        if ($this->pass == md5($passActual)) {
            $this->pass = $passNueva;
            return true;
        } else {
            return false;
        }
    }
    //FIN FUNCIONES DE SEGURIDAD

    //PROPIEDADES CALCULADAS
    public function calificacionesRecibidas ($filtro='%') { //Calificaciones Recibidas
        //el filtro va a ser para diferenciar mis calificaciones como comprador y vendedor
        $q = Doctrine_Query::create()
            ->select('c.*')
            ->from('calificacion c')
            ->innerJoin('c.calificado calificado')
            ->innerJoin('c.transaccion t')
            ->where('calificado.id = '.$this->id);
        return $q->execute();
    }
    public function calificacionesRealizadas ($filtro='%') { //Calificaciones Realizadas
        //el filtro va a ser para diferenciar mis calificaciones como comprador y vendedor
        $q = Doctrine_Query::create()
            ->select('c.*')
            ->from('calificacion c')
            ->innerJoin('c.calificante calificante')
            ->innerJoin('c.transaccion t')
            ->where('calificante.id = '.$this->id);
        return $q->execute();
    }

    public function conversaciones ($cuantos, $desde) {
        $q = Doctrine_Query::create()
            ->select('m.*')
            ->from('mensaje m')
            ->where('m.id in (SELECT max(mensaje.id) FROM mensaje GROUP BY mensaje.id_emisor)')
            ->andWhere('m.id_receptor = '.$this->id)
            ->orderBy('m.fecha desc')
            ->limit($cuantos) //cuantos trae
            ->offset($desde); //a partir de donde empieza a traer
        return $q->execute();
    }
    
    public function conversacionCon ($cuantos, $desde, $usuario) {
       $q = Doctrine_Query::create()
            ->select('m.*')
            ->from('mensaje m')
            ->where('m.id_receptor = '.$this->id.' and m.id_emisor = '.$usuario)
            ->orWhere('m.id_receptor = '.$usuario.' and m.id_emisor = '.$this->id)
            ->orderBy('m.fecha desc')
            ->limit($cuantos) //cuantos trae
            ->offset($desde); //a partir de donde empieza a traer
        return $q->execute();
    }
    
    public function mensajesEnviados ($filtro='%') { //Mensajes Enviados
        //el filtro va a ser para diferenciar mensajes leidos de no leidos
        $q = Doctrine_Query::create()
            ->select('m.*')
            ->from('mensaje m')
            ->innerJoin('m.emisor e')
            ->where('e.id = '.$this->id);
        return $q->execute();
    }

    public function ventas ($filtro='%') { //Ventas
        //el filtro va a ser para diferenciar ventas calificadas de no calificadas
        $q = Doctrine_Query::create()
            ->select('t.*')
            ->from('transaccion t')
            ->innerJoin('t.vendedor v')
            ->where('v.id = '.$this->id);
        return $q->execute();
    }
    public function compras ($filtro='%') { //Compras
        //el filtro va a ser para diferenciar compras calificadas de no calificadas
        $q = Doctrine_Query::create()
            ->select('t.*')
            ->from('transaccion t')
            ->innerJoin('t.comprador c')
            ->where('c.id = '.$this->id);
        return $q->execute();
    }
    
    // denuncias //
    public function usuariosDenunciados ($filtro='%') { //Usuarios Denunciados
        //el filtro va a ser para diferenciar las denuncias hechas de las recibidas
        $q = Doctrine_Query::create()
            ->select('d.*')
            ->from('denunciaUsuario d')
            ->innerJoin('d.denunciante dn')
            ->innerJoin('d.tipo t')
            ->where('t.contenido = "usuario"')
            ->andWhere('dn.id = '.$this->id);
        return $q->execute();
    }
    public function publicacionesDenunciadas ($filtro='%') { //Publicaciones Denunciadas
        //el filtro va a ser para diferenciar las denuncias hechas de las recibidas
        $q = Doctrine_Query::create()
            ->select('d.*')
            ->from('denunciaPublicacion d')
            ->innerJoin('d.denunciante dn')
            ->innerJoin('d.tipo t')
            ->where('t.contenido = "publicacion"')
            ->andWhere('dn.id = '.$this->id);
        return $q->execute();
    }
    public function markersDenunciados ($filtro='%') { //Markers Denunciados
        //el filtro va a ser para diferenciar las denuncias hechas de las recibidas
        $q = Doctrine_Query::create()
            ->select('d.*')
            ->from('denunciaMarker d')
            ->innerJoin('d.denunciante dn')
            ->innerJoin('d.tipo t')
            ->where('t.contenido = "marker"')
            ->andWhere('dn.id = '.$this->id);
        return $q->execute();
    }
    //FIN PROPIEDADES CALCULADAS

    //ACCIONES QUE REALIZA UN USUARIO
    public function calificar ($transaccion, $puntos, $comentario='') {
        $calificado = ($transaccion->vendor->id == $this->id)?$transaccion->comprador:$transaccion->vendor;
        $calificacion = new Calificacion ();
        $calificacion->calificante = $this;
        $calificacion->calificado = $calificado;
        $calificacion->transaccion = $transaccion;
        $calificacion->puntos = $puntos;
        $calificacion->comentario = $comentario;
        $calificacion->save();
    }
    //FIN ACCIONES QUE REALIZA UN USUARIO
    
    //FAVORITOS
   public function inFavoritos ($tabla, $objeto) {
        $q = Doctrine_Query::create()
            ->select('f.*')
            ->from($this->tablas[$tabla]['refClass'].' f')
            ->where('f.'.$this->tablas[$tabla]['local'].' = '.$this->id)
            ->andWhere('f.id_seguidor = '.$objeto->id);
        $resultado = $q->execute();
        return $resultado->count();
    }
    
    public function addFavorito ($tabla, $objeto) {
        if ($tabla == 'marker') {
            $this->markersFavoritos[] = $objeto;
        }
        if ($tabla == 'ccoperativa') {
            $this->cooperativasFavoritas[] = $objeto;
        }
        if ($tabla == 'usuario') {
            $this->usuariosFavoritos[] = $objeto;
        }
        if ($tabla == 'publicacion') {
            $this->publicacionesFavoritas[] = $objeto;
        }
    }
    
    public function removeFavorito ($tabla, $objeto) {
        $q = Doctrine_Query::create()
            ->delete($this->tablas[$tabla]['refClass'])
            ->where($this->tablas[$tabla]['local'].' = '.$this->id)
            ->andWhere('id_seguidor = '.$objeto->id);
	$q->execute();
    }
    
    public function favoritos ($tabla, $cuantos, $desde) {
        $q = Doctrine_Query::create()
            ->select('m.*')
            ->from('marker m, '.$this->tablas[$tabla]['refClass'].' f')
            ->where('m.id in (select f.id_seguidor from favorito_'.$tabla.' where '.$this->tablas[$tabla]['local'].' = '.$this->id.')')
            ->limit($cuantos) //cuantos trae
            ->offset($desde); //a partir de donde empieza a traer
        return $q->execute();
    }
    
    public function contarFavoritos ($tabla) {
         $q = Doctrine_Query::create()
            ->select('COUNT(m.id) as total')
            ->from('marker m, '.$this->tablas[$tabla]['refClass'].' f')
            ->where('m.id in (select f.id_seguidor from favorito_'.$tabla.' where '.$this->tablas[$tabla]['local'].' = '.$this->id.')');
         $total = $q->execute();
         return ($total->count())?$total[0]->total:0;
    }
    
    
    private $tablas = array (
        'marker'=> array('refClass'=>'FavoritoMarker', 'local'=>'id_marker_favorito'),
        'cooperativa'=>array('refClass'=>'FavoritoCooperativa', 'local'=>'id_cooperativa_favorito'),
        'usuario'=>array('refClass'=>'FavoritoUsuario', 'local'=>'id_usuario_favorito'),
        'publilcacion'=>array('refClass'=>'FavoritoPublicacion', 'local'=>'id_publicacion_favorita')
     );
    //FIN FAVORITOS
}
?>